package hao.itheima.aop;


import hao.itheima.entity.Emp;
import hao.itheima.entity.EmpLoginInfo;
import hao.itheima.entity.Result;
import hao.itheima.mapper.EmpLoginMapper;
import hao.itheima.mapper.OperateLogMapper;
import hao.itheima.pojo.EmpLoginLog;
import hao.itheima.pojo.OperateLog;
import hao.itheima.utils.CurrentHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.info.JavaInfoContributor;
import org.springframework.cglib.core.Local;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
public class LogAspect02 {

    @Autowired
    private OperateLogMapper operateLogMapper;

    @Autowired
    private EmpLoginMapper empLoginMapper;

    //1.记录日志
    @Around("@annotation(hao.itheima.annotation.Log)")// 切入点表达式--> 基于注解  --> 作用层是controller层
    public Object recordLogMessage(ProceedingJoinPoint joinPoint) throws Throwable {
        //0.首先创建一个对象,用于封装数据
        OperateLog operateLog = new OperateLog();
        //1.操作人-- > 就是获取操作人的id --> 基于ThreadLocal进行获取
        operateLog.setId(CurrentHolder.getCurrentId());
        //2.操作时间
        operateLog.setOperateTime(LocalDateTime.now());
        //3.执行方法的全类名(就是所在的类名)
        //
        operateLog.setClassName(joinPoint.getTarget().getClass().getName());
        //4.执行方法名
        operateLog.setMethodName(joinPoint.getSignature().getName());
        //5.方法运行时参数
        operateLog.setMethodParams(Arrays.toString(joinPoint.getArgs()));
        //6.方法执行时长
        //6.1获取当前时间
        long begin = System.currentTimeMillis();
        //6.2执行目标方法, 并获取结果
        Object result = joinPoint.proceed();
        //6.3设置返回值
        operateLog.setReturnValue(result.toString());
        //6.4获取执行后的时间
        long end = System.currentTimeMillis();
        //6.5计算方法执行时长
        operateLog.setCostTime(begin - end);

        //9.存入日志表
        operateLogMapper.insert(operateLog);
        //7.返回结果
        return result;
    }

    //需求: 记录登录操作
    /*@Around("execution(* hao.itheima.controller.LoginController.login(..))")
    public Object recordLoginLogMessage(ProceedingJoinPoint joinPoint) throws Throwable {
        //1.创建EmpLogInfo对象封装结果
        EmpLoginLog loginInfo = new EmpLoginLog();
        //实验一:
        //2.执行目标方法
        Object result = joinPoint.proceed();
        //2、直接获取参数
        Object[] args = joinPoint.getArgs();
        Emp emp = (Emp) args[0];
        //3、封装用户名
        loginInfo.setUsername(emp.getUsername());
        //4、封装密码
        loginInfo.setPassword(emp.getPassword());
        //5、封装操作时间
        loginInfo.setLoginTime(LocalDateTime.now());
        //6、登录是否成功
        Result result1 = (Result) result;
        loginInfo.setIsSuccess((short) (result1.getCode() == 1 ? 1 : 0));
        //7、获取Token
        hao.itheima.entity.EmpLoginInfo emploginlog = (EmpLoginInfo) result1.getData();
        loginInfo.setJwt(emploginlog.getToken());

        //8、调用Mapper方法将信息存储入表中
        empLoginMapper.insert(loginInfo);
        return result;
    }*/


    /**
     * 作业
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("execution(* hao.itheima.controller.LoginController.login(..))")
    public Object recordLoginLog(ProceedingJoinPoint joinPoint) throws Throwable {
        //joinPoint封装了前端传过来的所有数据, 可以直接获取
        // 获取方法参数 - 用户名和密码
        Object[] args = joinPoint.getArgs();
        Emp emp = (Emp) args[0];
        String username = emp.getUsername();
        String password = emp.getPassword();

        // 记录开始时间
        long startTime = System.currentTimeMillis();
        LocalDateTime loginTime = LocalDateTime.now();

        // 执行原始方法
        Object result = joinPoint.proceed();

        // 计算耗时
        long endTime = System.currentTimeMillis();
        long costTime = endTime - startTime;

        // 解析结果
        Result loginResult = (Result) result;
        Short isSuccess = (short) (loginResult.getCode() == 1 ? 1 : 0);
        hao.itheima.entity.EmpLoginInfo emploginlog = (EmpLoginInfo) loginResult.getData();
        String jwt = null;
        if (emploginlog != null){
            jwt = emploginlog.getToken();
          }

        // 构建日志对象
        EmpLoginLog log = new EmpLoginLog();
        log.setUsername(username);
        log.setPassword(password);
        log.setLoginTime(loginTime);
        log.setIsSuccess(isSuccess);
        log.setJwt(jwt);
        log.setCostTime(costTime);

        // 保存日志
        empLoginMapper.insert(log);

        return result;
    }
}
